package com.shd.day03;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import com.shd.day01.Apple;

/**
 * 方法推导
 * 
 * @author S5343
 * @date 2018年7月22日上午11:17:52
 */
public class MethodReference {

	public static void main(String[] args) {
		Consumer<String> consumer = (s) -> System.out.println(s);
		// 1
		useConsumer(consumer, "Hello world1");
		// 2
		useConsumer((s) -> System.out.println(s), "Hello world2");
		// 3
		useConsumer(System.out::println, "Hello world3");

		List<Apple> list = Arrays.asList(new Apple("green", 150), new Apple("red", 200), new Apple("green", 200));
		// 1
		list.sort(new Comparator<Apple>() {

			@Override
			public int compare(Apple o1, Apple o2) {
				return o1.getColor().compareTo(o2.getColor());
			}
		});
		// 2
		list.sort((o1, o2) -> o1.getColor().compareTo(o2.getColor()));
		// 3
		list.sort(Comparator.comparing(Apple::getColor));
		System.out.println(list);

		list.stream().forEach(a -> System.out.println(a));
		// 结果同上
		list.stream().forEach(System.out::println);

		// 方法推导场景
		/*
		 * 1.A method reference to a static method (for example, the method parseInt of
		 * Integer, written Integer::parseInt)
		 */
		int value = Integer.parseInt("123");

		Function<String, Integer> f = Integer::parseInt;
		f.apply("123");

		/*
		 * 2.A method reference to an instance method of an arbitrary type (for example,
		 * the method length of a String, written String::length)
		 */
		BiFunction<String, Integer, Character> function = String::charAt;
		Character c = function.apply("Hello", 1);
		System.out.println(c);

		/*
		 * 3.A method reference to an instance method of an existing object (for
		 * example, suppose you have a local variable expensiveTransaction that holds an
		 * object of type Transaction, which supports an instance method getValue; you
		 * can write expensiveTransaction::getValue)
		 */
		String s = "abcd";
		Function<Integer, Character> function2 = s::charAt;
		Character c1 = function2.apply(1);
		System.out.println(c1);

		// 构造函数
		Supplier<String> supplier = String::new;
		String string = supplier.get();
		System.out.println(string);

		// 两个参数
		BiFunction<String, Long, Apple> biFunction = Apple::new;
		Apple apply = biFunction.apply("Red", 123L);
		System.out.println(apply);

		// 三个参数自己定义Function
		ThreeFunction<String, Long, String, ComplexApple> threeFunction = ComplexApple::new;
		ComplexApple complexApple = threeFunction.apply("Red", 12L, "fushi");
		System.out.println(complexApple);

	}

	private static <T> void useConsumer(Consumer<T> consumer, T t) {
		consumer.accept(t);
		consumer.accept(t);
	}
}
